/* eslint-disable */
import { createWindyLayerNew } from './wind2';
import sjccKey from "@/config/sjmapkey";
const PLUGINS = [
  'SGMap.DistrictTask',
  'SGMap.MeteorologicalPlusLayer',
  'SGMap.WindLayer',
  'SGMap.GeocodingTask',
  'SGMap.GeometryUtil',
];
function parseColorAndValueArray(t) {
  const e = {
    colorArray: [],
    colorValArray: [],
  };
  for (let a = 0; a < t.length; a += 1) {
    e.colorArray[a] = t[a].color.replace('rgb', 'rgba').replace(')', ',0.3)');
    e.colorValArray[a] = t[a].min == null ? -1 / 0 : t[a].min;
    e.colorValArray[a] = t[a].val || t[a].min || t[a].max;
  }
  return e;
}
export const wind2uv = (wspd, wdir) => {
  return {
    u: wspd * Math.sin(((wdir + 180) / 360) * 2 * Math.PI),
    v: wspd * Math.cos(((wdir + 180) / 360) * 2 * Math.PI),
  };
};
export const grid2windData = (wind) => {
  // eslint-disable-next-line no-unused-vars
  const { gridInfo, gridData, windDirect } = wind;
  const lonNum = 321;
  const lonMax = 116.25;
  const lonSpan = 0.025000000000005684;
  const latSpan = 0.02500000000000213;
  const latMin = 28.9;
  const lonMin = 108.25;
  const latMax = 33.4;
  const latNum = 181;
  const header = {
    la1: latMax,
    la2: latMin,
    lo1: lonMin,
    lo2: lonMax,
    extent: [lonMin, latMin, lonMax, latMax],
    nx: lonNum,
    ny: latNum,
    dx: lonSpan,
    dy: latSpan,
  };
  const realData1 = gridData.reverse().flat(Infinity);
  const realData2 = windDirect.reverse().flat(Infinity);
  realData1.forEach((wspd, index) => {
    const wdir = realData2[index];
    const { u, v } = wind2uv(wspd, wdir);
    realData1[index] = u;
    realData2[index] = v;
  });
  return [
    {
      header: {
        ...header,
        min: Math.min(...realData1),
        max: Math.max(...realData1),
        parameterCategory: 2,
        parameterNumber: 2,
      },
      data: realData1,
    },
    {
      header: {
        ...header,
        parameterCategory: 2,
        parameterNumber: 3,
        min: Math.min(...realData2),
        max: Math.max(...realData2),
      },
      data: realData2,
    },
  ];
};

export default class WeatherMap {
  constructor(option = {}) {
    this._markersOnScreen = {};
    this.startx = 0;
    this.starty = 0;
    this.endx = 0;
    this.endy = 0;
    this.map = null;
    this.adcode = '';
    const { plugin = [], ...opt } = option;
    // 默认创建地图参数
    const defaultOptions = {
      container: 'warrmapcomponents',
      style: 'aegis://styles/aegis/Streets',
      // style: 'aegis://styles/aegis/HillShade',
      minZoom: 6.8,
      //   minZoom: 6.4,
      center: [112.301861, 31.234498],
      //   maxBounds: [
      //     [106.2, 28.4],
      //     [118.3, 33.9],
      //   ],
      localIdeographFontFamily: 'Microsoft YoHei',
    };
    this.options = { ...defaultOptions, ...opt };
    this.plugins = [...PLUGINS, ...plugin];
  }
  get markersOnScreen() {
    return this._markersOnScreen;
  }
  async init() {
    // 思极地图认证
    await this.mapAuthor();
    // 加载插件
    await this.loadPlugin();
    // 创建地图
    return this.createMap();
  }

  // 加载插件
  loadPlugin() {
    if (!Array.isArray(this.plugins)) return;
    const uniqPlugins = this.plugins.filter((i) => !Object.prototype.hasOwnProperty.call(SGMap, i.split('.').pop()));
    if (!uniqPlugins.length) return Promise.resolve([]);
    return SGMap.plugin(uniqPlugins);
  }

  // 创建地图
  createMap() {
    return new Promise((reslove, reject) => {
      this.map = new SGMap.Map(this.options);
      reslove(this.map);
    });
  }
  mapAuthor() {
    return SGMap.tokenTask.login(sjccKey.appkey, sjccKey.appsecret);
  }
  // 添加图层，addlayer
  addLayer(opt) {
    this.map.addLayer(opt);
  }
  getLayer(opt) {
    this.map.getLayer(opt);
  }
  // 添加图层，addlayer
  addSource(name, opt) {
    this.map.addSource(name, opt);
  }
  //切换影像图层
  changeStyle() {
    var t = this.map.getStyle();
    return new Promise((reslove, reject) => {
      SGMap.ajax({
        method: 'GET',
        type: 'json',
        headers: {
          Authorization: SGMap.config.ACCESS_TOKEN,
        },
        url: SGMap.config.API_URL + '/styles/v1/aegis/StreetsLight',
      })
        .then((r) => {
          if (r.glyphs) {
            t.glyphs = r.glyphs;
          }
          if (r.sprite) {
            t.sprite = r.sprite;
          }
          if (r.xml) {
            t.xml = r.xml;
          }
          t.layers = r.layers
            .filter((i) => !['ProvincialCapital', 'Town', 'City', 'County'].includes(i.id))
            .concat(t.layers);
          // 添加天气预警图表
          //   t.layers = r.layers.concat(
          //     t.layers.filter((e) => {
          //       if (['power-line', 'mask-polygon', 'power-polygen-symbol', 'Satellite512'].includes(e.id)) {
          //         return true
          //       }
          //       return false
          //     })
          //   )
          t.sources = Object.assign(t.sources, r.sources);
          this.map.setBaseStyle(t, {
            diff: false,
          });
          reslove(t);
        })
        .catch((err) => reject(err));
    });
  }
  // 获取资源
  getSource(opt) {
    this.map.getSource(opt);
  }
  // 绘制湖北省边框线
  createMask() {
    const { map } = this;
    // 行政区划边界线
    map.addLayer({
      id: 'power-line',
      type: 'line',
      source: {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: [],
        },
      },
      paint: {
        'line-color': '#f4b271',
        'line-width': 2,
      },
    });
    // 面标注
    map.addLayer({
      id: 'power-polygen-symbol',
      type: 'symbol',
      source: {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: [],
        },
      },
    });
    // 遮罩面
    map.addLayer({
      id: 'mask-polygon',
      type: 'fill',
      source: {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: [],
        },
      },
      paint: {
        'fill-color': '#061835',
        'fill-outline-color': '#061835',
      },
    });
  }
  // adcode=null,绘制全省，adcode=adcode,绘制对应城市数据
  addBound(adcode = null) {
    this.createMask();
    // this.map.addSource('dem', {
    //   type: 'raster',
    //   url: 'aegis://aegis.HillShade',
    // });
    // this.map.addLayer(
    //   {
    //     id: 'hillshading',
    //     source: 'dem',
    //     type: 'raster',
    //     // insert below waterway-river-canal-shadow;
    //     // where hillshading sits in the Mapbox Outdoors style
    //   },
    //   'power-line'
    // );
    // console.log('添加边界');
    return this.getFeature(adcode);
  }
  //添加maker
  createMaker(features) {
    for (const feature of features) {
      const coords = feature.geometry.coordinates;
      const props = feature.properties;
      const id = props.name;
      const adcode = props.adcode;
      let marker = this.markersOnScreen[id];
      let htmls = `<div id="box${props.adcode}" class="city-box" style="color:#fff;font-size: 16px;font-weight: bold;"><div class="city-name">${props.name}</div><div class="city-name" id="id${props.adcode}">${props.temperature}</div></div>`;

      if (!marker) {
        const el = document.createElement('div');
        el.innerHTML = htmls;
        marker = new SGMap.Marker({
          element: el,
          offset: [0, 15],
        }).setLngLat(coords);
        marker.addTo(this.map);
        this._markersOnScreen[id] = marker;
      } else {
        const id = `#box${adcode}`;
        const style = getComputedStyle(document.querySelector(id));
        if (style && style.display === 'none') {
          document.querySelector(id).style.display = 'block';
        }
      }
    }
    // 返回一个清理marker的函数
    const clear = () => {
      for (const id in this._markersOnScreen) {
        if (this._markersOnScreen[id]) {
          this._markersOnScreen[id].remove();
          this._markersOnScreen[id] = null;
        }
      }
    };
    this.clearMarker = clear;
    return clear;
  }
  //更新marker
  updateMaker(adcode, value) {
    const id = `#${adcode}`;
    if (document.querySelector(id)) {
      document.querySelector(id).innerHTML = value;
    }
  }
  //清除maker
  toggleMarker(features, flag = false) {
    for (let i in features) {
      const id = `#box${features[i].properties.adcode}`;
      if (document.querySelector(id)) {
        document.querySelector(id).style.display = flag ? 'block' : 'none';
      }
    }
  }
  //设置属性
  setStyleProperty(key, val) {
    let doms = document.querySelectorAll('.city-box');
    for (let i = 0; i < doms.length - 1; i++) {
      doms[i].style[key] = val;
    }
  }
  //隐藏温度值
  toggletemperture(features, flag) {
    for (let i in features) {
      const id = `#id${features[i].properties.adcode}`;
      if (document.querySelector(id)) {
        document.querySelector(id).style.display = flag ? 'block' : 'none';
      }
    }
  }
  // 获取切片数据
  getFeature(adcode) {
    const { map } = this;
    return new Promise((reslove, reject) => {
      const baseURL = process.env.NODE_ENV === "test" ? "test" : "hb-ecs";
      fetch(`/${baseURL}/json/hubei.json`)
        .then((r) => r.json())
        .then((result) => {
          var features = [];
          var featuresSymbol = [];
          var featuresPolygon = [];
          // 外层遮罩方形边界
          var outSideShape = [
            [
              [-180, 90],
              [180, 90],
              [180, -90],
              [-180, -90],
            ],
          ];
          // 主要区分直辖市和其他省份
          var district = result.data.districts[0];
          this.map.district = district;
          // if (adcode) {
          //   district = district.sub_districts.find((i) => i.adcode === adcode || i.name.includes(adcode));
          //   this.map.flyTo({
          //     center: district.center.split(','),
          //     zoom: 8,
          //     essential: true,
          //   });
          // } else {
          //   this.map.flyTo({
          //     center: [112.301861, 31.234498],
          //     zoom: 6.8,
          //     essential: true,
          //   });
          // }

          const flatarr = (pid, data, children = 'sub_districts') => {
            return data.reduce((prev, cur) => {
              return cur[children]
                ? prev.concat({ pid, ...cur }, flatarr(cur.name, cur[children]))
                : prev.concat({ pid, ...cur });
            }, []);
          };
          const allDistricts = flatarr(district.name, district.sub_districts).map((item) => ({
            type: 'Feature',
            geometry: {
              coordinates: item.center.split(',').map(Number),
              type: 'Point',
            },
            properties: {
              level: item.name === '神农架林区' ? 'city' : item.level,
              adcode: item.adcode,
              pid: item.pid,
              name: item.name,
              temperature: '',
            },
          }));
          // const cityDistricts = allDistricts.filter((i) => i.properties.level === 'city');
          const countyDistricts = allDistricts.filter((i) => i.properties.level === 'county');

          // 限制最大显示范围，也可以初始化地图的时候用maxZoom设置一个最大展示层级
          //   map.setMaxBounds(district.bbox.split(","));
          for (var o in district.sub_districts) {
            if (district.sub_districts[o].shape == undefined) continue;
            var shape = district.sub_districts[o].shape;
            var shapeMultiPolygon = [];

            // 标注
            // featuresSymbol.push({
            //   type: 'Feature',
            //   geometry: {
            //     coordinates: district.sub_districts[o].center.split(',').map(Number),
            //     type: 'Point',
            //   },
            //   properties: {
            //     name: district.sub_districts[o].name,
            //     temperature: '',
            //   },
            // });
            // 边界
            // if (shape.type == 'MultiPolygon') {
            //   for (const o in shape.coordinates) {
            //     if (shape.coordinates[o] instanceof Array) {
            //       features = features.concat(shape.coordinates[o]);
            //     }
            //   }
            // } else {
            //   features.push(shape.coordinates[0]);
            // }
          }
          // 面数据和遮罩
          // if (district.shape.type == 'MultiPolygon') {
          //   for (const o in district.shape.coordinates) {
          //     outSideShape = outSideShape.concat(district.shape.coordinates[o]);
          //     featuresPolygon = featuresPolygon.concat([district.shape.coordinates[o]]);
          //   }
          // } else {
          //   outSideShape = outSideShape.concat(district.shape.coordinates);
          //   featuresPolygon = featuresPolygon.concat(district.shape.coordinates);
          // }
          // 更新视图
          // 遮罩
          // map.getSource('mask-polygon').setData({
          //   type: 'FeatureCollection',
          //   features: [
          //     {
          //       type: 'Feature',
          //       geometry: {
          //         type: 'MultiPolygon',
          //         coordinates: [outSideShape],
          //       },
          //     },
          //   ],
          // });

          // 行政区划边界
          // map.getSource('power-line').setData({
          //   type: 'FeatureCollection',
          //   features: [
          //     {
          //       type: 'Feature',
          //       geometry: {
          //         type: 'MultiLineString',
          //         coordinates: features,
          //       },
          //     },
          //   ],
          // });
          // 面标注数据
          map.getSource('power-polygen-symbol').setData({
            type: 'FeatureCollection',
            // features: adcode ? districts : allDistricts,
            features: allDistricts,
          });
          this.createMaker(allDistricts);
          this.toggleMarker(countyDistricts);
          // map.on('zoomend', (e) => {
          //   const zoom = map.getZoom();
          //   if (this.adcode) return false;
          //   if (zoom > 8) {
          //     this.toggleMarker(countyDistricts, true);
          //     this.toggleMarker(cityDistricts, true);
          //   } else {
          //     this.toggleMarker(cityDistricts, true);
          //     this.toggleMarker(countyDistricts, false);

          //   }
          // });
          reslove(result);
        })
        .catch((e) => reject(e));
    });
  }
  updateBound(adcode) {
    if (adcode) {
      this.adcode = adcode;
      const districtTask = new SGMap.DistrictTask();

      districtTask
        .searchDistrict({
          keyword: adcode,
          // 建议直辖市取2，其他省份取1，提升请求速度
          subdistrict: 2,
          extension: true,
        })
        .then((result) => {
          var features = [];
          var featuresSymbol = [];
          var featuresPolygon = [];
          // 外层遮罩方形边界
          var outSideShape = [
            [
              [-180, 90],
              [180, 90],
              [180, -90],
              [-180, -90],
            ],
          ];
          // 主要区分直辖市和其他省份
          var district = result.data.districts[0];
          this.map.district = district;
          // 面数据和遮罩
          if (district.shape.type == 'MultiPolygon') {
            for (const o in district.shape.coordinates) {
              outSideShape = outSideShape.concat(district.shape.coordinates[o]);
              featuresPolygon = featuresPolygon.concat([district.shape.coordinates[o]]);
            }
          } else {
            outSideShape = outSideShape.concat(district.shape.coordinates);
            featuresPolygon = featuresPolygon.concat(district.shape.coordinates);
          }
          // 更新视图
          for (var o in district.sub_districts) {
            if (district.sub_districts[o].shape == undefined) continue;
            var shape = district.sub_districts[o].shape;

            // 标注
            featuresSymbol.push({
              type: 'Feature',
              geometry: {
                coordinates: district.sub_districts[o].center.split(',').map(Number),
                type: 'Point',
              },
              properties: {
                name: district.sub_districts[o].name,
                temperature: '',
              },
            });
            // 边界
            if (shape.type == 'MultiPolygon') {
              for (const o in shape.coordinates) {
                if (shape.coordinates[o] instanceof Array) {
                  features = features.concat(shape.coordinates[o]);
                }
              }
            } else {
              features.push(shape.coordinates[0]);
            }
          }
          // 遮罩
          this.map.getSource('mask-polygon').setData({
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                geometry: {
                  type: 'MultiPolygon',
                  coordinates: [outSideShape],
                },
              },
            ],
          });

          // 边界
          if (district.shape && district.shape.type == 'MultiPolygon') {
            for (const o in district.shape.coordinates) {
              if (district.shape.coordinates[o] instanceof Array) {
                features = features.concat(district.shape.coordinates[o]);
              }
            }
          } else {
            features.push(district.shape.coordinates[0]);
          }
          // 行政区划边界
          this.map.getSource('power-line').setData({
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                geometry: {
                  type: 'MultiLineString',
                  coordinates: features,
                },
              },
            ],
          });
          const featuresArr = this.map.getSource('power-polygen-symbol').serialize().data.features;
          let districts = featuresArr.find(
            (i) => i.properties.pid.includes(adcode) || i.adcode === adcode || i.properties.name.includes(adcode)
          );
          const outSideFeatures = featuresArr.filter((item) => !item.properties.pid.startsWith(adcode));
          const innerSideFeatures = featuresArr.filter(
            (item) => item.properties.pid.startsWith(adcode) || item.properties.name.startsWith(adcode)
          );
          console.log('outSideFeatures', outSideFeatures, innerSideFeatures);
          this.toggleMarker(outSideFeatures, false);
          this.toggleMarker(innerSideFeatures, true);
          const zoomMap = {
            武汉: 8.2,
            荆州: 8.2,
            黄石: 9.2,
            宜昌: 8,
            襄阳: 8,
            孝感: 8.3,
            荆门: 8.5,
            黄冈: 8,
            鄂州: 9.6,
            咸宁: 8.6,
            十堰: 8,
            随州: 8.8,
            恩施: 7.75,
            神农架: 9.5,
          };
          console.log(adcode, zoomMap[adcode]);
          console.log(districts.geometry.coordinates);
          this.map.flyTo({
            center: districts ? districts.geometry.coordinates : [110.47373909787217, 31.57815441880254],
            zoom: zoomMap[adcode],
          });
        })
        .catch((e) => console.log(e));
    } else {
      this.adcode = '';
      const baseURL = process.env.NODE_ENV === "test" ? "test" : "hb-ecs";
      fetch(`/${baseURL}/json/hubei.json`)
        .then((r) => r.json())
        .then((result) => {
          var features = [];
          var featuresSymbol = [];
          var featuresPolygon = [];
          // 外层遮罩方形边界
          var outSideShape = [
            [
              [-180, 90],
              [180, 90],
              [180, -90],
              [-180, -90],
            ],
          ];
          // 主要区分直辖市和其他省份
          var district = result.data.districts[0];
          this.map.district = district;
          // 面数据和遮罩
          if (district.shape.type == 'MultiPolygon') {
            for (const o in district.shape.coordinates) {
              outSideShape = outSideShape.concat(district.shape.coordinates[o]);
              featuresPolygon = featuresPolygon.concat([district.shape.coordinates[o]]);
            }
          } else {
            outSideShape = outSideShape.concat(district.shape.coordinates);
            featuresPolygon = featuresPolygon.concat(district.shape.coordinates);
          }
          for (var o in district.sub_districts) {
            if (district.sub_districts[o].shape == undefined) continue;
            var shape = district.sub_districts[o].shape;
            var shapeMultiPolygon = [];

            // 标注
            featuresSymbol.push({
              type: 'Feature',
              geometry: {
                coordinates: district.sub_districts[o].center.split(',').map(Number),
                type: 'Point',
              },
              properties: {
                name: district.sub_districts[o].name,
                temperature: '',
              },
            });
            // 边界
            if (shape.type == 'MultiPolygon') {
              for (const o in shape.coordinates) {
                if (shape.coordinates[o] instanceof Array) {
                  features = features.concat(shape.coordinates[o]);
                }
              }
            } else {
              features.push(shape.coordinates[0]);
            }
          }
          this.map.getSource('power-line').setData({
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                geometry: {
                  type: 'MultiLineString',
                  coordinates: features,
                },
              },
            ],
          });
          // 遮罩
          this.map.getSource('mask-polygon').setData({
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                geometry: {
                  type: 'MultiPolygon',
                  coordinates: [outSideShape],
                },
              },
            ],
          });
          this.map.flyTo({
            center: [112.301861, 31.234498],
            zoom: 6.8,
          });
        })
        .catch((e) => console.log(e));
    }
  }
  setLayoutProperty(layer, name, value) {
    this.map.setLayoutProperty(layer, name, value);
  }
  // 添加风层
  createWind({ opt = {}, data, colorConfig }) {
    const response = grid2windData(data);
    // const response = res.data
    //   console.log(JSON.stringify(_.chunk(res.data[0].data, 321).slice(0, 181)));
    //   console.log(JSON.stringify(_.chunk(res.data[1].data, 321).slice(0, 181)));
    const datas = response.map((item, idx) => {
      item.header = Object.assign(item.header, {
        parameterCategory: 2,
        parameterNumber: idx === 0 ? 2 : 3,
      });
      return item;
    });
    // eslint-disable-next-line new-cap
    const windyLayer = new createWindyLayerNew(this.map, 'windyLayerCanvas', {
      data: datas,
      colorScale: parseColorAndValueArray(colorConfig).colorArray,
    });
    if (!this.map.getSource('canvas-wind')) {
      const bbox = this.map.getBounds();
      const lnglat = [
        bbox.getNorthWest().toArray(),
        bbox.getNorthEast().toArray(),
        bbox.getSouthEast().toArray(),
        bbox.getSouthWest().toArray(),
      ];
      this.map.addSource('canvas-wind', {
        type: 'canvas',
        canvas: 'windyLayerCanvas',
        coordinates: lnglat,
        // Set to true if the canvas source is animated. If the canvas is static, animate should be set to false to improve performance.
        animate: true,
      });
    }
    this.map.on('moveend', () => {
      const bbox = this.map.getBounds();
      const lnglat = [
        bbox.getNorthWest().toArray(),
        bbox.getNorthEast().toArray(),
        bbox.getSouthEast().toArray(),
        bbox.getSouthWest().toArray(),
      ];
      this.map.getSource('canvas-wind').setCoordinates(lnglat);
    });
    this.map.addLayer({
      before: 'power-line',
      id: 'canvas-wind-layer',
      type: 'raster',
      source: 'canvas-wind',
    });
    this.map.moveLayer('canvas-wind-layer', 'power-line');
    return {
      ...windyLayer,
      remove: () => {
        this.map.removeLayer('canvas-wind-layer');
        this.map.removeSource('canvas-wind');
        windyLayer.remove();
      },
      update: (data) => windyLayer.update(grid2windData(data)),
      stop: () => windyLayer._stopWind(),
      start: () => windyLayer._startWindy(),
    };
    // add windy Layer
    // this.map.addLayer(windyLayer);
    // console.log(datas);
    // console.log({
    //   frameRate: 10,
    //   maxAge: 60,
    //   globalAlpha: 0.9,
    //   velocityScale: 0.0000001,
    //   // paths: 10000,
    //   paths: 10,
    //   ...opt
    // });
    // const windLayer = new SGMapWind.WindLayer("wind", datas, {
    //   windOptions: {
    //     frameRate: 16,
    //     maxAge: 60,
    //     globalAlpha: 0.1,
    //     velocityScale: 0.001,
    //     // paths: 10000,
    //     paths: 3782,
    //     ...opt
    //   }
    // });
    // windLayer.addTo(this.map);
    // console.warn("windLayer", windLayer);
    // return windLayer;
  }
}
